#ifndef _SPACEDISCR_H_
#define _SPACEDISCR_H_
#include "config.hpp"
#include "defs.h"
#include "fluid.h"
#include "geometry.h"
#include "utility.hpp"

class SpaceDiscr {
private:
  // public:
  VarArray<ConsVar_t, 2, 0> diss;
  VarArray<ConsVar_t, 2, 0> rhs;
  VarArray<Grad_t, 2, 0> gradFi;
  VarArray<Grad_t, 2, 0> gradFj;
  // 充当临时缓存的角色  注意值的合法性
  VarArray<real_t, 2, 0> u;
  VarArray<real_t, 2, 0> v;

  const VarArray<Area_t, 2, 0> &si, &sj;
  const VarArray<real_t, 2, 0> &vol;
  const VarArray<DeptVarE_t, 2, 0> &dvE;
  const VarArray<DeptVarNS_t, 2, 0> &dvNS;
  const VarArray<ConsVar_t, 2, 0> &cv;
  const VarArray<real_t, 2, 0> &press;
  const std::vector<BoundDescrp_t> &BoundDescrp;
  const real_t limCoef, epsEntr;
  real_t volRef;
  // limRef, 已经无量纲化了，不再需要
  const ConvectFlux_t convFluxType;
  const Equation_t equsType;
  const int pExtrNum;
  const int imax, // !< max. dimensions in i-direction (0 <= i <= imax); imax =
                  // nci + 3
      jmax, // !< max. dimensions in j-direction (0 <= j <= jmax); jmax = ncj +
            // 3
      il,   //  !< index of the 1st dummy cell in i-direction (right side); il =
            //  imax - 1
      jl,   //  !< index of the 1st dummy cell in j-direction (top side); jl =
            //  jmax - 1
      i2,   //  !< index of the last physical cell in i-direction; i2 = imax - 2
            //  (physical cells start at index 2)
      j2;   // !< index of the last physical cell in j-direction; j2 = jmax - 2
            // (physical cells start at index 2)

  void EntropyCorrect(const real_t &Gamac, const real_t &delta,
                      real_t &returnVar) const {
    returnVar =
        (delta < Gamac) ? Gamac : 0.5 * (Gamac * Gamac + delta * delta) / delta;
  }

  // template <typename T>
  void FluxBoundary(const BoundDescrp_t &Bdescrp);
  // template <typename T>
  void FluxRoeBoundary(const BoundDescrp_t &Bdescrp);

public:
  // SpaceDiscr(/* args */);
  ~SpaceDiscr() = default;
  SpaceDiscr(const SpaceDiscr &src) = delete;
  SpaceDiscr(SpaceDiscr &&src) = delete;
  SpaceDiscr &operator=(const SpaceDiscr &src) = delete;
  SpaceDiscr &operator=(SpaceDiscr &&src) = delete;

  SpaceDiscr(const Config &cfg, const Geometry &geo, Fluid &flow);
  // gradients
  void GradientInitial(void);
  void GradientFaceI(void);
  void GradientFaceJ(void);
  void FluxViscous(void);

  void SetDissipationZero(void) { diss = ConsVar_t{0.0, 0.0, 0.0, 0.0}; }
  VarArray<ConsVar_t, 2, 0> &GetRhs(void) { return rhs; }
  void DissipRoe1(void);
  void FluxRoe1(void);

  const VarArray<Grad_t, 2, 0> &GetGradientFaceI(void) const { return gradFi; }
  const VarArray<Grad_t, 2, 0> &GetGradientFaceJ(void) const { return gradFj; }
  const std::vector<BoundDescrp_t> &GetBoundaryDiscrpAll(void) const {
    return BoundDescrp;
  }
  const VarArray<Area_t, 2, 0> &GetSI(void) const { return si; }
  const VarArray<Area_t, 2, 0> &GetSJ(void) const { return sj; }
};

#endif